package cluster

import (
	"github.com/spf13/cast"

	"gitee.com/zfd81/dbrs/cluster/msgpb"

	"github.com/sirupsen/logrus"

	"github.com/hashicorp/memberlist"
)

type event struct{}

// NotifyJoin 当检测到节点已加入时，将调用NotifyJoin。
// 不能修改节点参数。
func (ed *event) NotifyJoin(node *memberlist.Node) {
	if Self() != nil {
		member := Member(*node)
		mtx.Lock()
		members[node.Name] = member
		mtx.Unlock()
		logrus.Info("A member joined: " + member.ServAddress())
		if IsLeader() {
			msg := NewMessage(msgpb.Action_ELECT)
			msg.Add(leader.Id)
			msg.Add(cast.ToString(leader.TimeStamp))
			err := msg.Send()
			if err != nil {
				logrus.Errorf("%v", err)
			}
		}
	}
}

// NotifyLeave 当检测到节点已离开时，将调用NotifyLeave。
// 不能修改节点参数。
func (ed *event) NotifyLeave(node *memberlist.Node) {
	mtx.Lock()
	delete(members, node.Name)
	mtx.Unlock()
	logrus.Warn("A member left: " + Member(*node).ServAddress())
	if len(members) == 1 {
		leader.BeElected()
	}
}

// NotifyUpdate 当检测到节点已更新时(通常涉及元数据)，将调用NotifyUpdate。
// 不能修改节点参数。
func (ed *event) NotifyUpdate(node *memberlist.Node) {
	member := Member(*node)
	mtx.Lock()
	members[node.Name] = member
	mtx.Unlock()
	logrus.Info("A member updated: " + member.ServAddress())
}
